<template>
  <a-modal
    destroyOnClose
    :title="title"
    :width="800"
    :visible="visible"
    :confirmLoading="confirmLoading"
    @ok="handleOk"
    @cancel="handleCancel"
    cancelText="关闭"
  >
    <a-spin :spinning="confirmLoading">
      <a-form :form="form">
        <a-form-item :labelCol="labelCol" :wrapperCol="wrapperCol" label="接口名称">
          <a-input
            placeholder="请输入接口名称"
            v-decorator="['serviceName', validatorRules.serviceName]"
            :disabled="disableSubmit"
          />
        </a-form-item>
        <a-form-item v-show="!editFlag" :labelCol="labelCol" :wrapperCol="wrapperCol" label="接口创建方式">
          <a-select
            placeholder="请选择接口创建方式"
            v-model="createMethod"
            :options="createMethodOptions"
            @change="handleCreateMethodChange"
          />
        </a-form-item>
        <a-form-item label="所属专题" :labelCol="labelCol" :wrapperCol="wrapperCol">
          <a-tree-select
            multiple
            placeholder="请选择所属专题"
            style="width: 100%;"
            :replaceFields="replaceFields"
            :dropdownStyle="{ maxHeight: '200px', overflow: 'auto' }"
            :treeData="topicTypes"
            v-decorator="['topicType']">
          </a-tree-select>

        </a-form-item>
        <a-form-item v-show="createMethod === '1' || (createMethod === '2' && !editFlag)" :labelCol="labelCol" :wrapperCol="wrapperCol" label="数据源">
          <a-select
            :disabled="editFlag || disableSubmit"
            placeholder="请选择数据源"
            v-decorator="['dataSourceCode', { rules: [{ required: createMethod === '1' || (createMethod === '2' && !editFlag), message: '请选择数据源!' }] }]"
            :options="dataSourceOptions"
            @change="handleDataSource"
          >
          </a-select>
        </a-form-item>
        <a-form-item v-show="createMethod !== '3'" :labelCol="labelCol" :wrapperCol="wrapperCol" label="数据表名称">
          <a-select
            :disabled="editFlag || disableSubmit"
            placeholder="请选择数据表名称"
            v-decorator="['tableName', { rules: [{ required: createMethod !== '3', message: '请选择数据表名称!' }] }]"
          >
            <a-select-option v-for="item in tableArr" :key="item.tableName">
              {{ item.tableName }}
            </a-select-option>
          </a-select>
        </a-form-item>
        <a-form-item v-show="createMethod === '3'" :labelCol="labelCol" :wrapperCol="wrapperCol" label="SQL">
          <div class="sql-editor-container">
            <SQLEditor
              ref="SQLEditor"
              :isShowSqlFormatButton="false"
              :sqlString="model.configSql"
              v-decorator="[
                'configSql',
                { rules: [{ required: createMethod === '3', message: '请输入SQL!' }, { validator: handleTestSql }] }
              ]"
              @input="getSqlContent"
            />
            <div class="sql-operate-button-container">
              <a-button @click="formatSqlContent">格式化SQL</a-button>
              <a-button style="margin-right: 0;" @click="testSqlContent">数据验证</a-button>
            </div>
          </div>
        </a-form-item>
        <a-form-item :labelCol="labelCol" :wrapperCol="wrapperCol" :label="editFlag ? '接口编码' : '接口编码生成方式'">
          <a-radio-group
            v-if="!editFlag"
            v-model="codeType"
            @change="handleCodeType"
            :disabled="disableSubmit || createMethod !== '1'"
          >
            <a-radio value="1">自定义</a-radio>
            <a-radio value="2">系统默认</a-radio>
          </a-radio-group>
          <a-input
            v-show="codeTypeFlag"
            placeholder="请输入服务编码"
            v-decorator="['serviceCode', { rules: [{ required: codeTypeFlag, message: '请输入编码!' }] }]"
          />
        </a-form-item>
        <a-form-item :labelCol="labelCol" :wrapperCol="wrapperCol" label="描述">
          <a-textarea placeholder="请输入描述" v-decorator="['serviceDesc']" :rows="4" :disabled="disableSubmit" />
        </a-form-item>
        <a-form-item :labelCol="labelCol" :wrapperCol="wrapperCol" label="状态">
          <j-dict-select-tag
            type="radio"
            v-decorator="['status', validatorRules.status]"
            :trigger-change="true"
            dictCode="status"
            :disabled="disableSubmit"
          />
        </a-form-item>
      </a-form>
    </a-spin>
    <InterfaceBySQLTestModal ref="sqlTestModal" @ok="testSqlSuccess" />
  </a-modal>
</template>

<script>
import pick from 'lodash.pick'
import SQLEditor from '@/components/SQLEditor'
import InterfaceBySQLTestModal from './interfaceBySQLTestModal'
import { httpAction, getAction } from '@/api/manage'

export default {
  name: 'InterfaceModal',
  components: {
    SQLEditor,
    InterfaceBySQLTestModal
  },
  data() {
    return {
      replaceFields: {
        children: 'childList',
        title: 'catalogName',
        key: 'id',
        value: 'id'
      },
      title: '操作',
      visible: false,
      editFlag: false,
      dataSourceOptions: [],
      model: {},
      codeType: '1',
      codeTypeFlag: true,
      labelCol: { xs: { span: 24 }, sm: { span: 5 }},
      wrapperCol: { xs: { span: 24 }, sm: { span: 16 }},
      confirmLoading: false,
      form: this.$form.createForm(this),
      validatorRules: {
        serviceName: { rules: [{ required: true, message: '请输入接口名称!' }] },
        status: { rules: [{ required: true, message: '请选择状态!' }] }
      },
      url: {
        getDataSourceList: '/sys/dataSource/list',
        getDataTablesList: '/index/config/listTables',
        add: '/index/scSituationIndexTopicServ/add',
        edit: '/index/scSituationIndexTopicServ/edit',
        checkName: '/index/scSituationIndexTopicServ/serviceDuplicateCheck'
      },
      tableArr: [],
      disableSubmit: false,
      createMethod: '1',
      createMethodOptions: [
        {
          value: '1',
          title: '根据数据表创建'
        },
        {
          value: '3',
          title: '根据SQL创建'
        }
      ],
      initSQLEditor: false,
      testSqlSuccessFlag: false,
      initSqlDataInEditMode: false,
      topicTypes: []
    }
  },
  created() {
    this.getDataSourceOptions()
    this.getTopicTypes()
  },
  methods: {
    getTopicTypes() {
      this.topicTypes = []
      getAction('/index/config/queryIndexCatalog', {}).then((res) => {
        if (res.success) {
          this.topicTypes = res.result
        }
      })
    },
    /**
     * @description 加载数据源下拉项
     * @returns void
     */
    getDataSourceOptions() {
      getAction(this.url.getDataSourceList, { pageNo: 1, pageSize: 1000 }).then(res => {
        if (res.success) {
          this.dataSourceOptions = res.result.records
          this.dataSourceOptions.map(item => {
            item.value = item.code
            item.title = item.name
          })
        } else {
          this.dataSourceOptions = []
        }
      })
    },

    /**
     * @description 变更接口创建方式事件响应
     * @returns void
     */
    handleCreateMethodChange(value) {
      if (value === '3') {
        // 当创建方式切换为3(即通过SQL方式创建时)
        this.codeType = '1' // 设置接口编码生成方式为自定义
        this.handleCodeType() // 手动触发接口编码生成方式变更事件响应
        this.form.resetFields(['dataSourceCode', 'tableName']) // 重置form的dataSourceCode字段,tableName字段
        this.form.setFieldsValue({ configSql: null }) // 重置form的SQL字段
        this.initSQLEditor = true // 设置sqlEditor初始化标识为true
        this.$refs.SQLEditor.handleEmptySqlContent() // 置空sqlEditor
      } else if (value === '1') {
        // 当创建方式切换为1(即通过数据表方式创建时)
        this.form.setFieldsValue({ configSql: null }) // 重置form的SQL字段
      }
    },

    /**
     * @description 切换数据源
     * @returns void
     */
    handleDataSource(value) {
      getAction(this.url.getDataTablesList, { code: value, filterService: true }).then(res => {
        if (res.success) {
          this.tableArr = res.result
        } else {
          this.tableArr = []
        }
      })
      this.form.resetFields(['tableName']) // 重置form的tableName字段
    },

    /**
     * @description 更改编码生成方式事件响应
     * @returns void
     */
    handleCodeType() {
      if (this.codeType === '1') {
        this.codeTypeFlag = true
      } else {
        this.codeTypeFlag = false
        this.form.setFieldsValue({ serviceCode: null })
      }
    },

    /**
     * @description 获取sqlEditor中的输入内容
     * @returns void
     */
    getSqlContent(value) {
      const content = value !== '' ? value : null
      this.form.setFieldsValue({ configSql: content }) // 设置form的configSql字段
      if (!content && !this.initSQLEditor) {
        // sql内容为空且当前sqlEditor初始化标识为false(非通过接口创建方式切换进行的初始化)时
        this.$nextTick(() => {
          this.form.validateFields(['configSql'], { force: true }) // 强制验证form的configSql字段
        })
      }
      // 默认sql输入值变化时，重置相关标识参数
      this.initSQLEditor = false // 重置sqlEditor初始化标识为false
      if (this.initSqlDataInEditMode) {
        this.initSqlDataInEditMode = !this.initSqlDataInEditMode // 当前为编辑初始化sql情况时，重置initSqlDataInEditMode标识参数
      } else {
        this.testSqlSuccessFlag = false // 非编辑初始化sql情况时，重置sql验证成功标识为false
      }
    },

    /**
     * @description sql数据验证前置检查
     * @returns void
     */
    handleTestSql(rule, value, callback) {
      if (!value) {
        callback()
      } else {
        if (this.testSqlSuccessFlag) {
          callback()
        } else {
          callback('请进行数据验证!')
        }
      }
    },

    /**
     * @description 格式化sqlEditor中的输入内容
     * @returns void
     */
    formatSqlContent() {
      this.$refs.SQLEditor.handleFormatSql() // 调用sqlEditor组件内部方式实现格式化
    },

    /**
     * @description 格式化sqlEditor中的输入内容
     * @returns void
     */
    testSqlContent() {
      const sqlContent = this.form.getFieldValue('configSql') // 获取sql输入值
      if (!sqlContent) {
        // 设置sql非空为前置验证条件
        this.$message.warning('请输入SQL!')
        return
      }
      this.$refs.sqlTestModal.sql = sqlContent // 传入sql验证组件sql输入值
      this.$refs.sqlTestModal.initData() // 初始化sql验证组件数据
    },

    /**
     * @description 验证成功后的回调方法
     * @returns void
     */
    testSqlSuccess() {
      this.testSqlSuccessFlag = true
      this.$nextTick(() => {
        this.form.validateFields(['configSql'], { force: true }) // 强制验证form的configSql字段
      })
    },

    /**
     * @description 添加操作
     * @returns void
     */
    add() {
      this.createMethod = '1'
      this.edit({})
    },

    /**
     * @description 编辑操作
     * @returns void
     */
    edit(record) {
      // 编辑时回显信息
      const keyArray = Object.keys(record)
      if (keyArray.length === 0) {
        this.editFlag = false
        this.codeTypeFlag = true
        this.codeType = '1'
      } else {
        // 查询数据表列表
        getAction(this.url.getDataTablesList, { code: record.dataSourceCode }).then(res => {
          if (res.success) {
            this.tableArr = res.result
          } else {
            this.tableArr = []
          }
        })
        this.createMethod = record.createType ? record.createType : '1'
        this.editFlag = true
        this.codeTypeFlag = true
        this.testSqlSuccess()
        this.initSqlDataInEditMode = true
      }
      this.form.resetFields()

      var topicTypeTemp = record.catalogIds != null && record.catalogIds != '' ? record.catalogIds.split(',') : []
      this.model = Object.assign({ status: '1', topicType: topicTypeTemp }, record)
      this.visible = true
      this.$nextTick(() => {
        this.form.setFieldsValue(pick(
          this.model,
          'serviceName',
          'configSql',
          'dataSourceCode',
          'tableName',
          'status',
          'topicType',
          'serviceDesc',
          'serviceCode'
        ))
      })
    },

    /**
     * @description 关闭操作
     * @returns void
     */
    close() {
      this.$emit('close')
      this.visible = false
    },

    /**
     * @description 取消操作
     * @returns void
     */
    handleCancel() {
      this.close()
    },

    /**
     * @description 确定操作
     * @returns void
     */
    handleOk() {
      // 触发表单验证
      this.form.validateFields({ force: true }, async(err, values) => {
        if (!err) {
          const formData = Object.assign(this.model, values)
          if (!this.model.id) {
            const obj = {
              serviceCode: this.codeType === '1' ? formData.serviceCode : formData.tableName
            }
            const res = await getAction(this.url.checkName, obj)
            if (res.code === 200) {
              if (res.result.has === 1) {
                const msg = this.codeType === '1' ? '用户输入的服务编码和已使用的服务编码重复，请修改！' : '数据表名称作为服务编码重复，请切换数据表名称！'
                this.$message.warning(msg)
                return
              }
            }
          }

          if (formData.topicType != null && formData.topicType.length > 0) {
            var topicTypeStr = formData.topicType.join(',')
            formData.catalogIds = topicTypeStr
          } else {
            formData.catalogIds = null
          }

          this.confirmLoading = true
          let httpUrl = this.url.add
          let method = 'post'
          if (this.model.id) {
            httpUrl = this.url.edit
            method = 'put'
          }
          httpAction(httpUrl, formData, method).then((res) => {
            if (res.success) {
              this.$message.success(res.message)
              this.$emit('ok')
              this.close()
            } else {
              this.$message.warning(res.message)
            }
          }).finally(() => {
            this.confirmLoading = false
          })
        }
      })
    }
  }
}
</script>

<style lang="less" scoped>
.sql-editor-container {
  width: 100%;
  height: 228px !important;
  overflow: auto;
  position: relative;
  line-height: 20px;
}
.sql-operate-button-container {
  margin-top: -32px;
  float: right;
}
</style>
